package apis

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-admin-team/go-admin-core/sdk/api"
	"github.com/go-admin-team/go-admin-core/sdk/pkg"
	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
	"net/http"
	"time"
	"tuowei.com/app/admin/models"
	"tuowei.com/app/admin/service"
	"tuowei.com/app/admin/service/dto"
	"tuowei.com/app/api/service/response"
	"tuowei.com/common/actions"
	Beans "tuowei.com/pkg/sing/beans"
	"tuowei.com/pkg/sing/http_utils"
	"tuowei.com/pkg/xlog"
)

type SysOrder struct {
	api.Api
	base
}

//线下订单详情
func (order SysOrder) GetOfflineOrderDetail(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.SysOfflineOrderDetailRequest{}
	err := order.MakeContext(ctx).MakeOrm().
		Bind(&req, binding.Default(ctx.Request.Method, ctx.ContentType())).
		MakeService(&s.Service).Errors
	if err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	//数据权限检查
	p := actions.GetPermissionFromContext(ctx)
	detail := models.OfflineOrder{}
	detail.Id = req.Id
	err = s.GetOfflineOrderDetail(&req, p, &detail)
	if err != nil {
		order.Error(500, err, "查询失败")
		return
	}
	// 获取订单操作记录
	records := make([]models.OfflineOrderProgress, 0)
	err = s.GetListsByOrderId(&records, detail.Id)
	if detail.SubjectRelation != nil {
		detail.Subject = detail.SubjectRelation.Name
	}
	if err != nil {
		order.Error(500, err, "查询失败")
		return
	}
	// 获取学生地区信息

	db, err := order.GetOrm()
	rsp := response.OfflineDetailResponse{}
	historyLists, _ := (&models.OfflineOrder{}).GetNealHalfYearHistoryList(db, detail.BuyerId, detail.Id)
	rsp.HistoryLists = historyLists
	rsp.Detail = detail
	rsp.Records = records
	order.OK(rsp, "success")

}

//在线订单详情
func (order SysOrder) GetOnlineOrderDetail(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.SysOnlineOrderDetailRequest{}
	err := order.MakeContext(ctx).MakeOrm().Bind(&req, binding.JSON, binding.Form).MakeService(&s.Service).Errors
	if err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	//数据权限检查
	p := actions.GetPermissionFromContext(ctx)

	detail := new(models.OnlineOrder)
	detail.Id = req.Id
	err = s.GetOnlineOrderDetail(&req, p, detail)
	if err != nil {
		order.Error(500, err, "查询失败")
		return
	}
	rsp := response.OnlineDetailResponse{}
	db, _ := order.GetOrm()
	historyLists, _ := (&models.OnlineOrder{}).GetNealHalfYearHistoryList(db, detail.BuyerId, detail.Id)
	rsp.Detail = *detail
	rsp.HistoryLists = historyLists
	order.OK(rsp, "success")
}

//

func (order SysOrder) DeliverGoods(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.SysDeliverGoodsRequest{}
	err := order.MakeContext(ctx).
		MakeOrm().
		Bind(&req, binding.Default(ctx.Request.Method, ctx.ContentType())).
		MakeService(&s.Service).Errors
	if err != nil {
		xlog.Error(err)
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	//数据权限检查
	p := actions.GetPermissionFromContext(ctx)
	model := new(models.MaterialOrder)
	if err = order.Orm.First(model, req.GetId()).Error; err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	req.Generate(model)
	userInfo := order.GetUser(ctx)
	model.DeliverId = userInfo.UserId
	err = s.UpdateByModel(model, p)
	if err != nil {
		order.Error(http.StatusInternalServerError, err, err.Error())
		return
	}
	//更新linkorder
	err = s.Orm.Table("sys_link_order").Where("order_type = 'MaterialOrder' and order_id=?", req.Id).Update("status", 4).Error
	if err != nil {
		xlog.Errorf("db error: %s", err)
		order.Error(http.StatusInternalServerError, err, err.Error())
		return
	}
	order.OK(model, "success")
}
func (order SysOrder) UpdateOnlineOrder(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.UpdateOnlineOrderRequest{}
	err := order.MakeContext(ctx).
		MakeOrm().
		Bind(&req, binding.Default(ctx.Request.Method, ctx.ContentType())).
		MakeService(&s.Service).Errors
	if err != nil {
		xlog.Error(err)
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	//数据权限检查
	p := actions.GetPermissionFromContext(ctx)
	model := new(models.OnlineOrder)
	if err = order.Orm.First(model, "order_number=?", req.GetOrderNumber()).Error; err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	req.Generate(model)
	err = s.UpdateOnlineByModel(model, p)
	if err != nil {
		order.Error(http.StatusInternalServerError, err, err.Error())
		return
	}
	order.OK(model, "success")
}

func (order SysOrder) UpdateMaterialOrder(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.UpdateMaterialOrderRequest{}
	err := order.MakeContext(ctx).
		MakeOrm().
		Bind(&req, binding.Default(ctx.Request.Method, ctx.ContentType())).
		MakeService(&s.Service).Errors
	if err != nil {
		xlog.Error(err)
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	//数据权限检查
	p := actions.GetPermissionFromContext(ctx)
	model := new(models.MaterialOrder)
	if err = order.Orm.First(model, "order_number=?", req.GetOrderNumber()).Error; err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	req.Generate(model)
	err = s.UpdateMaterialByModel(model, p)
	if err != nil {
		order.Error(http.StatusInternalServerError, err, err.Error())
		return
	}
	order.OK(model, "success")
}

// GetMaterialOrderDetail 获取资料订单详情
func (order SysOrder) GetMaterialOrderDetail(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.SysMaterialOrderDetailRequest{}
	err := order.MakeContext(ctx).
		MakeOrm().
		Bind(&req, binding.Default(ctx.Request.Method, ctx.ContentType())).
		MakeService(&s.Service).Errors
	if err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	//数据权限检查
	p := actions.GetPermissionFromContext(ctx)

	detail := new(models.MaterialOrder)
	rsp := response.MaterialDetailResponse{}
	err = s.GetMaterialOrderDetail(&req, p, detail)
	if err != nil {
		order.Error(500, err, "查询失败")
		return
	}
	if detail.SubjectRelation != nil {
		detail.Subject = detail.SubjectRelation.Name
	}
	rsp.Detail = *detail
	db, _ := order.GetOrm()
	historyList, _ := (&models.MaterialOrder{}).GetNealHalfYearHistoryList(db, detail.BuyerId, detail.Id)
	rsp.HistoryLists = historyList
	order.OK(rsp, "查询成功")
}

// AddMaterialOrder 新增资料订单
func (order SysOrder) AddMaterialOrder(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.SysMaterialOrderAddRequest{}
	err := order.MakeContext(ctx).
		MakeOrm().
		Bind(&req, binding.Default(ctx.Request.Method, ctx.ContentType())).
		MakeService(&s.Service).Errors
	if err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	// 设置创建人
	req.SetCreateBy(user.GetUserId(ctx), user.GetUserName(ctx))
	id, err := s.InsertMaterialOrder(&req)
	if err != nil {
		order.Logger.Error(err)
		order.Error(500, err, err.Error())
		return
	}
	order.OK(id, "创建成功")
}

//GetOfflineOrderList 线下订单列表
func (order SysOrder) GetOfflineOrderList(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.SysOfflineOrderListRequest{}
	err := order.MakeContext(ctx).MakeOrm().
		Bind(&req, binding.Default(ctx.Request.Method, ctx.ContentType())).
		MakeService(&s.Service).Errors
	if err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	//数据权限检查
	p := actions.GetPermissionFromContext(ctx)
	list := make([]models.OfflineOrder, 0)
	var count int64
	var totalMoney float64

	err = s.GetOfflineOrderList(&req, p, &list, &count, &totalMoney)
	if err != nil {
		order.Error(500, err, "查询失败")
		return
	}
	for k := range list {
		if list[k].SubjectRelation != nil {
			list[k].Subject = list[k].SubjectRelation.Name
		}
	}
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"requestId": pkg.GenerateMsgIDFromContext(ctx),
		"code":      http.StatusOK,
		"msg":       "查询成功",
		"data": map[string]interface{}{
			"count":     count,
			"pageIndex": req.GetPageIndex(),
			"pageSize":  req.GetPageSize(),
			"sum":       totalMoney,
			"list":      list,
		},
	})
	//order.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "success")

}

// GetMaterialOrderList 资料订单列表
func (order SysOrder) GetMaterialOrderList(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.SysMaterialOrderListRequest{}
	err := order.MakeContext(ctx).MakeOrm().
		Bind(&req, binding.Default(ctx.Request.Method, ctx.ContentType())).
		MakeService(&s.Service).Errors
	if err != nil {
		order.Error(500, err, err.Error())
		return
	}
	// 权限检测
	p := actions.GetPermissionFromContext(ctx)
	list := make([]models.MaterialOrder, 0)
	var count int64
	var totalMoney float64
	err = s.GetMaterialOrderList(&req, p, &list, &count, &totalMoney)
	if err != nil {
		order.Error(500, err, "查询失败")
		return
	}
	for k := range list {
		if list[k].SubjectRelation != nil {
			list[k].Subject = list[k].SubjectRelation.Name
		}
	}
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"requestId": pkg.GenerateMsgIDFromContext(ctx),
		"code":      http.StatusOK,
		"msg":       "查询成功",
		"data": map[string]interface{}{
			"count":     count,
			"pageIndex": req.GetPageIndex(),
			"pageSize":  req.GetPageSize(),
			"sum":       totalMoney,
			"list":      list,
		},
	})
	//order.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")

}

// AddOnlineOrder 新增在线订单
func (order SysOrder) AddOnlineOrder(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.SysOnlineOrderAddRequest{}
	err := order.MakeContext(ctx).
		MakeOrm().
		Bind(&req, binding.Default(ctx.Request.Method, ctx.ContentType())).
		MakeService(&s.Service).Errors
	if err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	// 设置创建人
	req.SetCreateBy(user.GetUserId(ctx), user.GetUserName(ctx))
	id, err := s.InsertOnlineOrder(&req)
	if err != nil {
		order.Logger.Error(err)
		order.Error(500, err, err.Error())
		return
	}
	order.OK(id, "创建成功")
}

// AddOfflineOrder 新增线下订单
func (order SysOrder) AddOfflineOrder(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.SysOfflineOrderAddRequest{}
	err := order.MakeContext(ctx).
		MakeOrm().
		Bind(&req, binding.Default(ctx.Request.Method, ctx.ContentType())).
		MakeService(&s.Service).Errors
	if err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	//后台系统添加线下订单接口，未用

	// 设置创建人
	req.SetCreateBy(user.GetUserId(ctx), user.GetUserName(ctx))
	id, err := s.InsertOfflineOrder(&req)
	if err != nil {
		order.Logger.Error(err)
		order.Error(500, err, err.Error())
		return
	}
	order.OK(id, "创建成功")
}

// 在线订单列表
func (order SysOrder) GetOnlineOrderList(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.SysOnlineOrderListRequest{}
	err := order.MakeContext(ctx).
		MakeOrm().
		Bind(&req, binding.Default(ctx.Request.Method, ctx.ContentType())).
		MakeService(&s.Service).
		Errors
	if err := req.ParseTime(); err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	if err != nil {
		order.Error(500, err, err.Error())
		return
	}

	//数据权限检查
	p := actions.GetPermissionFromContext(ctx)

	list := make([]models.OnlineOrder, 0)
	var count int64
	var totalMoney float64
	err = s.GetOnlineOrderList(&req, p, &list, &count, &totalMoney)
	if err != nil {
		order.Error(500, err, "查询失败")
		return
	}
	for k := range list {
		if list[k].SubjectRelation != nil {
			list[k].Subject = list[k].SubjectRelation.Name
		}
	}
	//xlog.Pretty(list)
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"requestId": pkg.GenerateMsgIDFromContext(ctx),
		"code":      http.StatusOK,
		"msg":       "查询成功",
		"data": map[string]interface{}{
			"count":     count,
			"pageIndex": req.GetPageIndex(),
			"pageSize":  req.GetPageSize(),
			"sum":       totalMoney,
			"list":      list,
		},
	})
	//order.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
}

//OfflineOrderRecheck 线下订单复审确认
func (order SysOrder) OfflineOrderRecheck(ctx *gin.Context) {
	s := service.SysOrder{}
	req := dto.SysOfflineOrderRecheckUpdateRequest{}
	err := order.MakeContext(ctx).MakeOrm().
		Bind(&req, binding.Default(ctx.Request.Method, ctx.ContentType())).
		MakeService(&s.Service).Errors
	if err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}

	err = s.Update(&req, ctx)
	if err != nil {
		order.Error(500, err, "复审失败")
		return
	}
	if req.RecheckOk == 1 {
		// 更新复审人id
		s.Orm.Model(models.OfflineOrder{}).Where("id = ?", req.Id).Update("recheck_user_id", order.GetUser(ctx).UserId)
		offlineOrderProgress := models.OfflineOrderProgress{}
		offlineOrderProgress.Status = 4
		offlineOrderProgress.Creator = "复审人-" + order.GetUser(ctx).Username
		offlineOrderProgress.OrderId = req.Id
		offlineOrderProgress.OperateTime = time.Now().Local()
		err = s.Orm.Create(&offlineOrderProgress).Error
		if err != nil {
			order.Logger.Errorf("db error: %s", err)
		}
	} else {
		offlineOrderProgress := models.OfflineOrderProgress{}
		offlineOrderProgress.Status = 2
		offlineOrderProgress.Creator = "复审驳回人-" + order.GetUser(ctx).Username
		offlineOrderProgress.OrderId = req.Id
		offlineOrderProgress.OperateTime = time.Now().Local()
		err = s.Orm.Create(&offlineOrderProgress).Error
		if err != nil {
			order.Logger.Errorf("db error: %s", err)
		}
	}

	order.OK(req.Id, "success")

}

// 系统账单
func (order SysOrder) GetBill(ctx *gin.Context) {
	s := service.SysOrder{}
	err := order.MakeContext(ctx).MakeOrm().
		MakeService(&s.Service).Errors
	if err != nil {
		order.Error(http.StatusBadRequest, err, err.Error())
		return
	}
	countStu, countLec, countOnl, countOff, countMat, err := s.GetBill()
	if err != nil {
		order.Error(500, err, "查询失败")
		return
	}

	type GetBillResp struct {
		CountStuSum                    int64       `json:"count_stu_sum"`
		CountLecSum                    int64       `json:"count_lec_sum"`
		CountOnlSum                    int64       `json:"count_onl_sum"`
		CountOffSum                    int64       `json:"count_off_sum"`
		CountMatSum                    int64       `json:"count_mat_sum"`
		CountOnlToday                  int64       `json:"count_onl_today"`
		CountOnlYesterday              int64       `json:"count_onl_yesterday"`
		CountOffToday                  int64       `json:"count_off_today"`
		CountOffYesterday              int64       `json:"count_off_yesterday"`
		CountMatToday                  int64       `json:"count_mat_today"`
		CountMatYesterday              int64       `json:"count_mat_yesterday"`
		CountOnlXList                  interface{} `json:"count_onl_x_list"`
		CountOnlHourCountListYesterday interface{} `json:"count_onl_hour_count_list_yesterday"`
		CountOffHourCountListYesterday interface{} `json:"count_off_hour_count_list_yesterday"`
		CountMatHourCountListYesterday interface{} `json:"count_mat_hour_count_list_yesterday"`
		CountOnlHourCountList          interface{} `json:"count_onl_hour_count_list"`
		CountOffHourCountList          interface{} `json:"count_off_hour_count_list"`
		CountMatHourCountList          interface{} `json:"count_mat_hour_count_list"`
	}

	b := GetBillResp{
		CountStuSum:   countStu,
		CountLecSum:   countLec,
		CountOnlSum:   countOnl,
		CountOffSum:   countOff,
		CountMatSum:   countMat,
		CountOnlXList: []string{"2:00", "4:00", "6:00", "8:00", "10:00", "12:00", "14:00", "16:00", "18:00", "20:00", "22:00", "24:00"},
	}

	b.CountOnlToday, b.CountOnlYesterday, b.CountOnlHourCountListYesterday, b.CountOnlHourCountList, err = s.GetBillTodayAndYesterday("countOnl")
	b.CountOffToday, b.CountOffYesterday, b.CountOffHourCountListYesterday, b.CountOffHourCountList, err = s.GetBillTodayAndYesterday("countOff")
	b.CountMatToday, b.CountMatYesterday, b.CountMatHourCountListYesterday, b.CountMatHourCountList, err = s.GetBillTodayAndYesterday("countMat")

	//xlog.Pretty(list)
	order.OK(b, "查询成功")
}

func (order SysOrder) AssignOrder(ctx *gin.Context) {
	var err error
	req := new(dto.AssignOrderRequest)
	err = order.MakeContext(ctx).MakeOrm().Bind(req, binding.JSON).Errors
	if err != nil {
		order.Error(http.StatusInternalServerError, err, err.Error())
		return
	}
	userInfo := order.GetUser(ctx)
	// 获取订单详情
	detail := models.OfflineOrder{}
	detail.Id = req.Id
	err = order.Orm.First(&detail).Error
	if err != nil {
		order.Error(http.StatusInternalServerError, err, "订单查询错误:"+err.Error())
		return
	}
	if detail.Status != models.OfflineStatusSubmit {
		order.Error(http.StatusInternalServerError, errors.New("该订单状态不是提交状态"), "该订单状态不是提交状态")
		return
	}
	// 查找用户
	teacher := new(models.SysUser)
	teacher.UserId = req.EnrollmentTeacherId
	err = order.Orm.First(&teacher).Error
	if err != nil {
		order.Error(http.StatusInternalServerError, err, "用户查询错误:"+err.Error())
		return
	}
	if !teacher.IsEnrollment() {
		order.Error(http.StatusInternalServerError, errors.New("分配老师必须是招生岗位的"), "分配老师必须是招生岗位的")
		return
	}
	// 查找学生
	stu := new(models.SysStudent)
	stu.Id = detail.BuyerId
	err = order.Orm.First(&teacher).Error
	if err != nil {
		order.Error(http.StatusInternalServerError, err, "订单学生查询错误:"+err.Error())
		return
	}
	// 更新订单招生老师id和状态
	detail.Status = models.OfflineStatusFollowIng
	detail.EnrollmentTeacherId = req.EnrollmentTeacherId
	txOrder := order.Orm.Updates(&detail)
	if txOrder.Error != nil {
		xlog.Error(err)
		//return err
	}
	// 更新学生的状态
	stu.EnrollmentTeacherId = req.EnrollmentTeacherId
	txStu := order.Orm.Updates(stu)
	if txStu.Error != nil {
		xlog.Error(err)
	}
	if err != nil {
		order.Error(http.StatusInternalServerError, err, err.Error())
		return
	}
	// 更新操作日志
	record := models.OfflineOrderProgress{}
	record.Creator = userInfo.NickName
	record.Status = models.OfflineStatusFollowIng
	record.OrderId = req.Id
	record.OperateTime = time.Now()
	record.Remarks = fmt.Sprintf("分配给招生老师%d,分配订单错误%v,影响行数%d,分配学员错误%v，影响行树%d",
		req.EnrollmentTeacherId, txOrder.Error, txOrder.RowsAffected, txStu.Error, txStu.RowsAffected)
	order.Orm.Save(&record)
	order.OK(detail, "分配成功")
}

func (order SysOrder) FileDownloadUrl(ctx *gin.Context) {
	order.MakeContext(ctx)
	signFlowId := ctx.Param("signFlowId")
	url := fmt.Sprintf("/v3/sign-flow/%s/file-download-url", signFlowId)
	r, httpStatus := http_utils.SendCommHttp(url, "", http.MethodGet)
	if httpStatus != http.StatusOK {
		order.Error(http.StatusInternalServerError, nil, "请求e电签接口错误")
		return
	}
	rsp := Beans.FileDownloadUrlRsp{}
	json.Unmarshal(r, &rsp)
	if rsp.Code != 0 {
		order.Error(http.StatusInternalServerError, nil, rsp.Message)
		return
	}
	order.OK(rsp.Data, rsp.Message)
}
